package com.mall.user.services;

import com.mall.user.ILoginService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dto.*;
import com.mall.user.utils.ExceptionProcessorUtils;
import com.mall.user.utils.JwtTokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.Map;


@Slf4j
@Component
@Service
public class LoginServiceImpl  implements ILoginService {

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    RedissonClient redissonClient;


    /**
     *  用户登录
     *
     */
    @Override
    public UserLoginResponse userLogin(UserLoginRequest userLoginRequest) {
        UserLoginResponse userLoginResponse = new UserLoginResponse();
        try{
            // 参数非空校验
            userLoginRequest.requestCheck();
            // 参数正确性校验  即 校验用户名和密码
//            Member validMemberUserNameAndPassword = new Member();
//            validMemberUserNameAndPassword.setUsername(userLoginRequest.getUserName());
//            validMemberUserNameAndPassword.setPassword(userLoginRequest.getPassword());
//            Member validedMember = memberMapper.selectOne(validMemberUserNameAndPassword);

//            Member validedMember = memberMapper.validLoginUserNameAndPassword(userLoginRequest.getUserName(),userLoginRequest.getPassword());
            // 获取加密后的密码
            String passwordEncode = memberMapper.getEncodedPassword(userLoginRequest.getUserName());
            String passwordLogin = DigestUtils.md5DigestAsHex(userLoginRequest.getPassword().getBytes());
            if(!passwordEncode.equalsIgnoreCase(passwordLogin)){
                // 用户名或密码错误
                userLoginResponse.setCode(SysRetCodeConstants.USERORPASSWORD_ERRROR.getCode());
                userLoginResponse.setMsg(SysRetCodeConstants.USERORPASSWORD_ERRROR.getMessage());
                return userLoginResponse;
            }

            // 校验用户账号是否已激活
            String memberVerifiedStatus = memberMapper.getUserVerifiedStatus(userLoginRequest.getUserName(),passwordEncode);
            if(!memberVerifiedStatus.equals("Y")){
                // 账号未激活
                userLoginResponse.setCode(SysRetCodeConstants.USER_ISVERFIED_ERROR.getCode());
                userLoginResponse.setMsg(SysRetCodeConstants.USER_ISVERFIED_ERROR.getMessage());
                return userLoginResponse;
            }

            // 获取用户id
            Member member = new Member();
            member.setUsername(userLoginRequest.getUserName());
            Member getUserIdMember = memberMapper.selectOne(member);

            // 将用户名和用户id保存到redisson中
            RMap<String,String> map =redissonClient.getMap("mapKey-34");
            // 存入用户名
            map.put("username",userLoginRequest.getUserName());
            // 存入用户id
            map.put("userId",String.valueOf(getUserIdMember.getId()));

            // 用户名、密码和激活状态都校验通过 给UserLoginResponse赋值
            // 头像
            String avatar = "https://pic.netbian.com/uploads/allimg/211029/113624-1635478584334b.jpg";
            // 获取一个合法JWT,msg值是用户名
            JwtTokenUtils jwtTokenUtils = JwtTokenUtils.builder().msg(userLoginRequest.getUserName()).build();
            String jwtTokenStr = jwtTokenUtils.creatJwtToken();

            UserLoginResponse loginResponseTarget = new UserLoginResponse(getUserIdMember.getId(), userLoginRequest.getUserName(), null, null, null,
                    null, avatar, null, 0, 0L, 1, jwtTokenStr);
            loginResponseTarget.setCode(SysRetCodeConstants.SUCCESS.getCode());
            loginResponseTarget.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
            return loginResponseTarget;
        } catch (Exception e){
            log.error("MemberServiceImpl.userLogin Occur Exception:" + e);
            userLoginResponse.setCode(SysRetCodeConstants.DB_EXCEPTION.getCode());
            userLoginResponse.setMsg(SysRetCodeConstants.DB_EXCEPTION.getMessage());
            ExceptionProcessorUtils.wrapperHandlerException(userLoginResponse,e);
            return userLoginResponse;
        }
    }


    /**
     *  解密验证cookie中的token
     *
     */
    @Override
    public CheckAuthResponse validToken(CheckAuthRequest checkAuthRequest){
        CheckAuthResponse checkAuthResponse = new CheckAuthResponse();
        try{
            //从cookie中获取token
            //TokenIntercepter中checkAuthRequest的token已经有值了，
            // 我们要做的事：取出token，解密token
            String token = checkAuthRequest.getToken();
            // 解密
            JwtTokenUtils jwtFreeTool = JwtTokenUtils.builder().token(token).build();
            String username = jwtFreeTool.freeJwt();
            // 从redis中获取存入的用户名
            RMap<String,String> map = redissonClient.getMap("mapKey-34");
            String targetUsername = map.get("username");
            if(!username.equals(targetUsername)){
                // 验证失败 -->  重新登录
                checkAuthResponse.setCode(SysRetCodeConstants.TOKEN_VALID_FAILED.getCode());
                checkAuthResponse.setMsg(SysRetCodeConstants.TOKEN_VALID_FAILED.getMessage());
                return checkAuthResponse;
            }
            // 验证成功
            RMap userInfoRedisMap = redissonClient.getMap("mapKey-34");
            // 给userInfo属性赋值
            Map userInfoMap = new HashMap();
            userInfoMap.put("username",userInfoRedisMap.get("username"));
            userInfoMap.put("uid",userInfoRedisMap.get("userId"));
            checkAuthResponse.setUserInfo(userInfoMap);
            checkAuthResponse.setCode(SysRetCodeConstants.SUCCESS.getCode());
            checkAuthResponse.setMsg(SysRetCodeConstants.SUCCESS.getMessage());
            return checkAuthResponse;
        } catch (Exception e){
            log.error("LoginServiceImpl.validToken Occur Exception:" + e);
            checkAuthResponse.setCode(SysRetCodeConstants.SYSTEM_ERROR.getCode());
            checkAuthResponse.setMsg(SysRetCodeConstants.SYSTEM_ERROR.getMessage());
            ExceptionProcessorUtils.wrapperHandlerException(checkAuthResponse,e);
            return checkAuthResponse;
        }
    }
}
